package com.czmh.etc.onlinepubsys.utils;

import cn.hutool.core.util.DesensitizedUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.czmh.etc.onlinepubsys.utils.wxpay.StringUtil;
import com.google.common.collect.Maps;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

/**
 * @描述：
 * @作者： Seven.
 * @创建日期：2017年1月3日 下午3:51:28.
 * @版本：1.0
 */
public class PayUtil {

    /**
     * 生成订单号
     *
     * @return
     */
    public static String getTradeNo() {
        // 自增8位数 00000001
        return "TNO" + DatetimeUtil.formatDate(new Date(), DatetimeUtil.TIME_STAMP_PATTERN);
    }

    /**
     * 退款单号
     *
     * @return
     */
    public static String getRefundNo() {
        // 自增8位数 00000001
        return "RNO" + DatetimeUtil.formatDate(new Date(), DatetimeUtil.TIME_STAMP_PATTERN);
    }

    /**
     * 退款单号
     *
     * @return
     */
    public static String getTransferNo() {
        // 自增8位数 00000001
        return "TNO" + DatetimeUtil.formatDate(new Date(), DatetimeUtil.TIME_STAMP_PATTERN);
    }

    /**
     * 返回客户端ip
     *
     * @param request
     * @return
     */
    public static String getRemoteAddrIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (StringUtil.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            // 多次反向代理后会有多个ip值，第一个ip才是真实ip
            int index = ip.indexOf(",");
            if (index != -1) {
                return ip.substring(0, index);
            } else {
                return ip;
            }
        }
        ip = request.getHeader("X-Real-IP");
        if (StringUtil.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            return ip;
        }
        return request.getRemoteAddr();
    }

    /**
     * 获取服务器的ip地址
     *
     * @param request
     * @return
     */
    public static String getLocalIp(HttpServletRequest request) {
        return request.getLocalAddr();
    }

    public static String getSign(Map<String, String> params, String paternerKey) throws UnsupportedEncodingException {
        return MD5Utils.getMD5(createSign(params, false) + "&key=" + paternerKey).toUpperCase();
    }

    /**
     * 构造签名
     *
     * @param params
     * @param encode
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String createSign(Map<String, String> params, boolean encode) throws UnsupportedEncodingException {
        Set<String> keysSet = params.keySet();
        Object[] keys = keysSet.toArray();
        Arrays.sort(keys);
        StringBuffer temp = new StringBuffer();
        boolean first = true;
        for (Object key : keys) {
            if (key == null || StringUtil.isEmpty(params.get(key))) // 参数为空不参与签名
            {
                continue;
            }
            if (first) {
                first = false;
            } else {
                temp.append("&");
            }
            temp.append(key).append("=");
            Object value = params.get(key);
            String valueStr = "";
            if (null != value) {
                valueStr = value.toString();
            }
            if (encode) {
                temp.append(URLEncoder.encode(valueStr, "UTF-8"));
            } else {
                temp.append(valueStr);
            }
        }
        return temp.toString();
    }

    /**
     * 创建支付随机字符串
     *
     * @return
     */
    public static String getNonceStr() {
        return RandomUtil.randomString(RandomUtil.LETTER_NUMBER_CHAR, 32);
    }

    /**
     * 支付时间戳
     *
     * @return
     */
    public static String payTimestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }

    /**
     * Url生成签名
     *
     * @param map      需要加密参数
     * @param appScret 密钥
     * @return
     */
    public static String generateSign(Map map, String appScret) throws Exception {
        StringBuffer stringBuffer = new StringBuffer();
        Map map1 = sortByKey(map, false);
        Iterator<Map.Entry> iterator = map1.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry next = iterator.next();
            stringBuffer.append(next.getKey());
            stringBuffer.append("=");
            stringBuffer.append(next.getValue());
            stringBuffer.append("&");
        }
        stringBuffer.deleteCharAt(stringBuffer.length() - 1);
        String sign = MD5Utils.getMD5(stringBuffer.toString() + appScret);
        return sign;
    }

    /**
     * 按照Map的Key值进行排序
     *
     * @param map    Map对象
     * @param isDesc 按照key值是否降序
     * @param <K>    返回值
     * @param <V>    返回值
     * @return
     */
    public static <K extends Comparable<? super K>, V> Map<K, V> sortByKey(Map<K, V> map, boolean isDesc) {
        Map<K, V> result = Maps.newLinkedHashMap();
        if (isDesc) {
            map.entrySet().stream().sorted(Map.Entry.<K, V>comparingByKey().reversed())
                    .forEachOrdered(e -> result.put(e.getKey(), e.getValue()));
        } else {
            map.entrySet().stream().sorted(Map.Entry.<K, V>comparingByKey())
                    .forEachOrdered(e -> result.put(e.getKey(), e.getValue()));
        }
        return result;
    }

    public static void main(String[] args) {
        try {
            JSONObject obj = new JSONObject();
            obj.put("vehiclePlate", "粤WQX255");
            obj.put("phone", DesensitizedUtil.desensitized("13533340708", DesensitizedUtil.DesensitizedType.MOBILE_PHONE));
            Map<String, String> m = new HashMap<>();
            m.put("remark", obj.toJSONString());
            m.put("request", "public.handle.cdk_activation");
            m.put("request_type", "request");
            m.put("platform", "wxxcx");
            m.put("cdk", "25FF764B346E");
            m.put("equipment_code", "XT-008K547213846204");
			m.put("class", "handle");
			m.put("method", "cdk_activation");
            String s = null;
            s = PayUtil.generateSign(m, "asfdaijfgpagpoas");
            m.put("sign", s.substring(8, 24).toUpperCase());
            String r = HttpUtils.doPost("https://klqqb.ganjiayou.com/etc/api/wxxcx/", m);
            if (!StringUtils.isEmpty(r)) {
                JSONObject jsonObject = JSON.parseObject(r);
                //{"msg":"签名验证失败","code":1}
				System.out.println(JSON.toJSONString(m));
                System.out.println(jsonObject.toJSONString());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
